#include "compile_run.hpp"
#include "../comm/util.hpp"
#include "../comm/httplib.h"

#include <string>
#include <functional>

#include "../message_queue/src/mqclient/mq_connection.hpp"
#include "../message_queue/src/mqcommon/mq_msg.pb.h"
#include <sw/redis++/redis++.h>

void Usag(char *proc)
{
    std::cout << "Usag:\n\t" << proc << " consumerName" << std::endl;
}

void writeToRedisList(const std::string &id,const std::string &res_json)
{
    //创建redis对象
    sw::redis::Redis redis("tcp://127.0.0.1:6379");

    //向列表右侧添加一个值
    auto result = redis.rpush(id,res_json);
    if (result < 0) 
    {
        ELOG("向列表右侧添加value失败");
        return;
    }

    //设置key的过期时间
    redis.expire(id,std::chrono::seconds(10));  //10秒的过期时间
}

void cb(mq::Channel::ptr channel,const std::string& c_tag,mq::BasicProperties *bp,const std::string &body)
{
    //进行编译服务
    std::string out_json;   //获取编译的结果json
    if(!body.empty())
         ns_compile_and_run::CompileAndRun::start(body,&out_json);
    
    //获取题目编号，作为redis的key
    Json::Value in_value;
    Json::Reader reader;
    reader.parse(body, in_value);
    std::string id = in_value["id"].asString();

    // 把结果加到Redis当中
    writeToRedisList(id,out_json);


    //确认应达
    channel->basicAck(bp->id());
}

int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        Usag(argv[0]);
        exit(1);
    }

    //1.定义异步工作线程
    mq::AsyncWorker::ptr worker = std::make_shared<mq::AsyncWorker>();
    //2.创建连接
    mq::Connection::ptr conn = std::make_shared<mq::Connection>("127.0.0.1",8888,worker);
    //3.创建信道
    mq::Channel::ptr channel = conn->openChannel();
    //4. 通过信道提供的服务完成所需
        //1.创建一个交换机
    google::protobuf::Map<std::string, std::string> args;
    channel->declareExchange("exchange1",mq::ExchangeType::FANOUT,true,false,args);
        //2.创建队列1
    channel->declareQueue("queue1",false,true,false,args);
        //4.绑定队列
    channel->queueBind("exchange1","queue1","queue1");
    
    auto Functor = std::bind(cb,channel,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3);

    //订阅队列1
    channel->basicConsume(argv[1],"queue1",false,Functor);

    while(1) std::this_thread::sleep_for(std::chrono::seconds(3));
    
    conn->closeChannel(channel);

    return 0;
}